import { computed, ref } from 'vue'

import { catchFn, wait } from '@/libs/common'
import { getQuizQuestion, sendQuizAnswer, sendQuizAnswerAuto } from '../../api'
import { startHomeResultTimeout } from '@/pages/main/components/home/data'
import { showHelpMask } from './help-mask/data'

/** 会话ID */
let sessionId = ''
/** 测评类型Code */
let typeCode = ''

/** 当前题目 */
const curQuestion = ref<T_Question>()
/** 回答列表 */
let questionList: (T_Question | number)[] = []

/** 当前回答 */
const curAnswerIdx = ref(-1)
/** 当前回答等级 */
const curAnswerLevel = ref(-1)
/** 回答列表 */
let answerList: number[] = []
/** 回答等级列表 */
let answerLevelList: number[] = []

/** 等级列表 */
const levelList: T_AnswerLevel[] = [
  {
    name: 'a l3',
    idx: 0,
    level: 3,
  },
  {
    name: 'a l2',
    idx: 0,
    level: 2,
  },
  {
    name: 'a l1',
    idx: 0,
    level: 1,
  },
  {
    name: 'c l1',
    idx: -1,
    level: 1,
  },
  {
    name: 'b l1',
    idx: 1,
    level: 1,
  },
  {
    name: 'b l2',
    idx: 1,
    level: 2,
  },
  {
    name: 'b l3',
    idx: 1,
    level: 3,
  },
]

const isFirst = computed(() => curQuestion.value?.progress.current === 1)
const isLast = computed(
  () => curQuestion.value?.progress.current === curQuestion.value?.progress.total,
)

export {
  sessionId,
  typeCode,
  curQuestion,
  curAnswerIdx,
  curAnswerLevel,
  levelList,
  isFirst,
  isLast,
}

/**
 * 开始答题
 * @param q 题目
 * @param count 题目总数
 */
const startTest = async (
  opt: {
    sessionId: string
    typeCode: string
    qustionsCount: number
  },
  questionId: number,
) => {
  sessionId = opt.sessionId
  typeCode = opt.typeCode

  const { data } = await getQuizQuestion(opt.sessionId, questionId)

  questionList[data.progress.current - 1] = curQuestion.value = data

  data.progress.current === 1 && setTimeout(() => (showHelpMask.value = true), 500)

  saveCache()

  uni.navigateTo({ url: '/pages/quiz/mbti/detail/index' })
}

/**
 * 开始答题（使用历史缓存）
 * @param data 历史缓存数据
 */
const startTestWithHistory = (json: string) =>
  catchFn(
    async () => {
      const data = JSON.parse(json)

      questionList = data.qL || []
      answerList = data.aL || []
      answerLevelList = data.aLL || []

      startTest(data, questionList[data.qL.length - 1] as number)
    },
    {
      onError: () => clearCache(),
    },
  )

/**
 * 缓存答题进度
 */
const saveCache = () => {
  if (!curQuestion.value) return

  const idx = curQuestion.value.progress.current - 1

  answerList[idx] = curAnswerIdx.value
  answerLevelList[idx] = curAnswerLevel.value

  uni.setStorageSync(
    'mbti_test',
    JSON.stringify({
      sessionId,
      typeCode,
      qL: questionList.map(item => (typeof item === 'number' ? item : item.id)),
      aL: answerList,
      aLL: answerLevelList,
    }),
  )
}

/**
 * 缓存答题进度
 */
const clearCache = () => uni.removeStorageSync('mbti_test')

/**
 * 选择答案级别
 * @param item 级别
 */
const selectLevel = (item: T_AnswerLevel) => {
  curAnswerIdx.value = item.idx
  curAnswerLevel.value = item.level

  !isLast.value && curAnswerIdx.value !== -1 && next()
}

/**
 * 上一题
 */
const pre = () => next(-1)

let isLoading = false

/**
 * 下一题
 */
const next = async (num = 1) => {
  if (isLoading) return
  else isLoading = true

  await catchFn(
    async () => {
      if (!curQuestion.value) return

      let idx = curQuestion.value.progress.current - 1

      if (answerList[idx] !== curAnswerIdx.value || answerLevelList[idx] !== curAnswerLevel.value) {
        const ans = curQuestion.value.options[curAnswerIdx.value]

        if (ans) {
          const { data } = await sendQuizAnswer(sessionId, curQuestion.value.id, ans.value)

          data.nextQuestionId && (questionList[idx + 1] = data.nextQuestionId)
        }

        await wait(200)
        saveCache()
      }

      idx += num

      curAnswerIdx.value = answerList[idx]
      curAnswerLevel.value = answerLevelList[idx]

      let q = questionList[idx]

      if (typeof q === 'number') {
        q = (await getQuizQuestion(sessionId, q)).data

        questionList[q.progress.current - 1] = q
      }

      curQuestion.value = q
    },
    { disableLoading: true },
  )

  isLoading = false
}

/**
 * 完成答题
 */
const finish = () =>
  catchFn(async () => {
    if (!curQuestion.value) return

    saveCache()

    const ans = curQuestion.value.options[curAnswerIdx.value]

    await sendQuizAnswer(sessionId, curQuestion.value.id, ans.value)

    // const { data } = await getQuizResult({ sessionId, typeCode })

    // result.value = data.mbtiResult

    // 回首页等待测试结果
    uni.redirectTo({ url: '/pages/main/index' })

    setTimeout(startHomeResultTimeout, 1000)

    clearCache()
  })

/**
 * 完成答题
 */
const finishAll = () =>
  catchFn(async () => {
    if (!curQuestion.value) return

    saveCache()

    const ans = curQuestion.value.options[curAnswerIdx.value] || curQuestion.value.options[0]

    await sendQuizAnswerAuto(sessionId, curQuestion.value.id, ans.value)

    // 回首页等待测试结果
    uni.redirectTo({ url: '/pages/main/index' })

    setTimeout(startHomeResultTimeout, 1000)

    clearCache()
  })

/**
 * 还原状态
 */
const clear = () => {
  sessionId = ''
  typeCode = ''
  isLoading = false

  curQuestion.value = undefined
  questionList = []

  curAnswerIdx.value = -1
  curAnswerLevel.value = -1
  answerList = []
  answerLevelList = []
}

export {
  startTest,
  startTestWithHistory,
  clearCache,
  selectLevel,
  pre,
  next,
  finish,
  finishAll,
  clear,
}
